package exper

import java.io.{OutputStream, InputStream}
import java.net.Socket

/**
 * Created by IntelliJ IDEA.
 * User: zslajchrt
 * Date: 5.3.11
 * Time: 10:45
 * To change this template use File | Settings | File Templates.
 */

abstract class ServletAPI {

  type ServletType <: Servlet
  type ServletRequestType <: ServletRequest
  type ServletResponseType <: ServletResponse

  val factory: Factory
  val servlet: ServletType = factory.newServlet

  trait Factory {
    def newServlet: ServletType
    def newRequest(input: InputStream): ServletRequestType
    def newResponse(output: OutputStream): ServletResponseType
  }

  trait Servlet {
    def service(request: ServletRequestType, response: ServletResponseType)
  }

  trait ServletRequest {
    def getServlet: ServletType
  }

  trait ServletResponse {
    def getServlet: ServletType
  }

  def consume(input: InputStream, output: OutputStream): ServletResponseType = {
    val req: ServletRequestType = factory.newRequest(input)
    val resp: ServletResponseType = factory.newResponse(output)
    servlet.service(req, resp)
    resp
  }
}

abstract class HttpServletAPI extends ServletAPI {

  type ServletType = HttpServlet
  type ServletRequestType = HttpServletRequest
  type ServletResponseType = HttpServletResponse

  trait HttpServlet extends Servlet {
    def service(request: ServletRequestType, response: ServletResponseType) {
      val uri = request.requestURI
    }
  }

  trait HttpServletRequest extends ServletRequest {
    def requestURI: String
  }

  trait HttpServletResponse extends ServletResponse

}

abstract class Container {

  val servletAPI: ServletAPI

  def handleRequest(socket: Socket) {
    val input = socket.getInputStream
    val output = socket.getOutputStream
    val response = servletAPI.consume(input, output)
  }

}

object HttpContainer extends Container with Application {
  val servletAPI: HttpServletAPI = null // todo

  init()

  def init() {
    // todo: hook itself on a TCP/IP port
  }
}